#include "stdafx.h"
#include <iostream>
#include <io.h>
#include <sys\stat.h>
#include "CapClient.h"
#include "DlgLogon.h"
#include "CapClientDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#pragma comment(lib, "ntdll.lib")
extern "C"  DWORD __stdcall NtNotifyChangeDirectoryFile (HANDLE, HANDLE, PVOID, PVOID, PVOID, PVOID, DWORD, DWORD, BOOL);

#define         THD_WATCH    0
#define         THD_SEARCH   1

HANDLE			g_hThreads[2][MAX_REC_PATH];
DWORD			g_nThreadIDs[2][MAX_REC_PATH];
bool            g_bThreadRun[2][MAX_REC_PATH];

CRITICAL_SECTION	g_crtSendFile;

BOOL SearchDirFile(CCapClientDlg *pDlg,int nCur,char* pSubDirName) 
{ 
	CFileFind tempFind; 
	char sTempFileFind[MAX_PATH] ;
	if (!g_RecPath[nCur].bEnable)
	{
		return FALSE ;
	}
	DWORD	atrb = GetFileAttributes(g_RecPath[nCur].szPath);
	if (!(atrb != 0xffffffff && (atrb & FILE_ATTRIBUTE_DIRECTORY)))
	{
		return FALSE ;
	}	
 	if(pSubDirName == NULL)
		sprintf_s(sTempFileFind,"%s*.*",g_RecPath[nCur].szPath);
	else
		sprintf_s(sTempFileFind,"%s%s*.*",g_RecPath[nCur].szPath,pSubDirName);
	BOOL bRet = TRUE ;
	BOOL bIsFinded = tempFind.FindFile(sTempFileFind); 
	while (bIsFinded) 
	{ 
		if( !g_bThreadRun[THD_SEARCH][nCur] )
		{
			break ;
		}
		bIsFinded = tempFind.FindNextFile(); 
 		if (!tempFind.IsDots()) 
		{ 
			if( !g_bThreadRun[THD_SEARCH][nCur] )
			{
				break ;
			}
			char sFoundFileName[MAX_PATH]; 
			strcpy(sFoundFileName,tempFind.GetFileName().GetBuffer(MAX_PATH)); 
 			if (tempFind.IsDirectory()) 
			{ 
				char sTempDir[MAX_PATH]; 
				if(pSubDirName == NULL)
					sprintf_s(sTempDir,"%s\\",sFoundFileName);
				else
					sprintf_s(sTempDir,"%s%s\\",pSubDirName,sFoundFileName);
				if( SearchDirFile(pDlg, nCur,sTempDir) == FALSE )
				{
					bRet = FALSE ;
					break;
				}
			} 
			else 
			{ 
				char sTempFileName[MAX_PATH]; 
				if(pSubDirName == NULL)
					sprintf_s(sTempFileName,"%s",sFoundFileName); 
				else
					sprintf_s(sTempFileName,"%s%s",pSubDirName,sFoundFileName); 

				if( !g_bThreadRun[THD_SEARCH][nCur] )
				{
					break ;
				}
				EnterCriticalSection (&g_crtSendFile);
				BOOL bRet = pDlg->SendFile(THD_SEARCH,nCur, sTempFileName);
				LeaveCriticalSection (&g_crtSendFile);
				if(bRet == FALSE)
				{
					break;
 				}
			} 
		} 
	} 
	tempFind.Close(); 
	return bRet; 
} 
DWORD CALLBACK  ThreadSearchFile (void *pWnd)
{
	CCapClientDlg* pDlg = (CCapClientDlg*)pWnd ;
	int i;
	int nCur = 0 ;
	for( i = 0; i < MAX_REC_PATH; i++)
	{
		if (g_nThreadIDs[THD_SEARCH][i] == GetCurrentThreadId())
		{
			nCur = i;
			break;
		}
	}
	SearchDirFile(pDlg,nCur,NULL) ;
	if( g_bThreadRun[THD_SEARCH][nCur] )
	{
		g_bThreadRun[THD_SEARCH][nCur] = false ;
		CloseHandle (g_hThreads[THD_SEARCH][nCur]);
		g_hThreads[THD_SEARCH][nCur] = NULL ;
 	}
	return nCur + 100000;
}

DWORD CALLBACK  ThreadWatchFile (void *pWnd)
{
	CCapClientDlg* pDlg = (CCapClientDlg*)pWnd ;
	int i;
	int nCur = 0 ;
	for( i = 0; i < MAX_REC_PATH; i++)
	{
		if (g_nThreadIDs[THD_WATCH][i]  == GetCurrentThreadId())
		{
			nCur = i;
			break;
		}
	}
	
	HANDLE hWatchFile = CreateFile (g_RecPath[nCur].szPath,
											FILE_LIST_DIRECTORY,
											FILE_SHARE_READ | FILE_SHARE_WRITE,
											NULL,
											OPEN_EXISTING,
											FILE_FLAG_BACKUP_SEMANTICS,
											NULL);
	DWORD	atrb;
	BYTE	buffer[1028];
	DWORD	io_status_block[2];
	for (;;)
	{
		if(!g_bThreadRun[THD_WATCH][nCur] )
		{
			break;
		}
		atrb = GetFileAttributes(g_RecPath[nCur].szPath);
		if (!(atrb != 0xffffffff && (atrb & FILE_ATTRIBUTE_DIRECTORY)))
		{
			break;
		}
		ZeroMemory (buffer, sizeof (buffer));
		NtNotifyChangeDirectoryFile(hWatchFile, 
									NULL,
									NULL,
									NULL,
									&io_status_block,
									&buffer,
									1024,
									FILE_NOTIFY_CHANGE_FILE_NAME,
									TRUE);
		if( g_bThreadRun[THD_WATCH][nCur] )
		{
			EnterCriticalSection (&g_crtSendFile);
			BOOL bRet = pDlg->SendFile(nCur, (FILE_NOTIFY_INFORMATION*)buffer);
			LeaveCriticalSection (&g_crtSendFile);
			if(bRet == FALSE)
			{
				break ;
			}
		}
		else
		{
			break;
		}
	}
	if( g_bThreadRun[THD_WATCH][nCur] )
	{
		g_bThreadRun[THD_WATCH][nCur]  = false;
		CloseHandle (g_hThreads[THD_WATCH][nCur]);
		g_hThreads[THD_WATCH][nCur] = NULL ;
 	}
	else
	{
		char szTmpFile[MAX_PATH];
		sprintf_s(szTmpFile,"%sDkqTmp.txt",g_RecPath[nCur].szPath);
		DeleteFile(szTmpFile);
	}
	CloseHandle (hWatchFile);
	hWatchFile = NULL;
 	return nCur + 200000;
}
BOOL CCapClientDlg::SendFile(int nCur, FILE_NOTIFY_INFORMATION *pBuffer)
{
   	if (pBuffer->Action == FILE_ACTION_ADDED)
	{
		char szFileName[256];
		DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,pBuffer->FileName,-1,NULL,0,NULL,FALSE);
		WideCharToMultiByte (CP_OEMCP,NULL,pBuffer->FileName,-1,szFileName,dwNum,NULL,FALSE);
		if(!SendFile(THD_WATCH,nCur,szFileName))
		{
			return FALSE ;
		}
	}
	if (pBuffer->NextEntryOffset)
	{
		return SendFile (nCur, (FILE_NOTIFY_INFORMATION*)((BYTE*)pBuffer + pBuffer->NextEntryOffset));
	}
	return TRUE ;
}
BOOL CCapClientDlg::HaveSend(int nThType,int nCur, char *szFileName)
{
	char szLog[MAX_PATH];
	char szMyFile[MAX_PATH];
	BOOL bRet = FALSE ;
	int nStrLen = strlen(szFileName);
	sprintf_s(szLog,"%sDkqLog.txt",g_RecPath[nCur].szPath);
	FILE *fp = fopen(szLog,"rt");
	if(fp != NULL)
	{
 		while(!feof(fp))
		{
			if( !g_bThreadRun[nThType][nCur])
			{
				break ;
			}
 			fgets(szMyFile,MAX_PATH,fp);
			if(_strnicmp(szFileName,szMyFile,nStrLen)==0)
			{
 				bRet = TRUE ;
				break;
			}
		}
 		fclose(fp);fp=NULL;
	}
	return bRet ;
}
BOOL CCapClientDlg::SendFile(int nThType,int nCur, char *szFileName)
{
	if(HaveSend(nThType,nCur, szFileName))
	{
		return TRUE;
	}
	if( !g_bThreadRun[nThType][nCur])
	{
		return TRUE;
	}
	FILE *fp ;

	char szFile[MAX_PATH];
	sprintf_s(szFile,"%s%s",g_RecPath[nCur].szPath,szFileName);
	fp = fopen(szFile,"rb");
	if(fp == NULL)
	{
		return FALSE ;
	}
	DWORD dwFileSize1 = 0 ;
	DWORD dwFileSize = filelength(fileno(fp));
	int nCyc = 0 ;
	while(dwFileSize==0 || dwFileSize1 < dwFileSize)
	{
		Sleep(500);
		dwFileSize = filelength(fileno(fp));
		dwFileSize1 = dwFileSize ;
		nCyc++;
		if (nCyc > 3)
		{
			break;
		}
	}
	if (dwFileSize == 0)
	{
		fclose(fp);fp=NULL;
		return TRUE ;
	}
	
	DDERR_CODE	ret = DD_Net_fwOpen(g_hLogin,szFile,dwFileSize);
	if (ret != DD_ERR_SUCCESS)
	{
		fclose(fp);fp=NULL;
		return FALSE ;
	}
	BYTE *pBuffer = (BYTE*) malloc(1024*1024+4);
	if(pBuffer == NULL)
	{
		fclose(fp);fp=NULL;
		return FALSE ;
	}
	DWORD dwTotal = 0 ;
	DWORD dwBufSize ; 
	while(!feof(fp))
	{
		dwBufSize = fread(pBuffer,1,1024*1024,fp);
		if(dwBufSize > 0)
		{
			ret = DD_Net_fWrite(g_hLogin,pBuffer,dwBufSize,&dwFileSize1,-1);
			if (ret != DD_ERR_SUCCESS)
			{
				DD_Net_fwClose(g_hLogin);
				fclose(fp);fp=NULL;
				free(pBuffer);pBuffer = NULL;
				return FALSE ;
			}
			dwTotal += dwBufSize ;
		}
		else
		{
			break ;
		}
 	}
	free(pBuffer);pBuffer = NULL;
	ret = DD_Net_fwClose(g_hLogin);
	if (ret != DD_ERR_SUCCESS)
	{
		fclose(fp);fp=NULL;
		return FALSE ;
	}

	char szLog[MAX_PATH];
	sprintf_s(szLog,"%sDkqLog.txt",g_RecPath[nCur].szPath);
	fp = fopen(szLog,"at");
	if(fp != NULL)
	{
		fputs(szFileName,fp);
		fputs("\n",fp);
		fflush(fp);
		fclose(fp);fp=NULL;
	}
	return TRUE ;
}
void CCapClientDlg::InitWatchFile()
{
	InitializeCriticalSection (&g_crtSendFile);
	int i;
	for( i = 0; i < MAX_REC_PATH; i++)
	{
		g_hThreads[THD_SEARCH][i] = NULL ;
		g_hThreads[THD_WATCH][i] = NULL ;
		g_bThreadRun[THD_WATCH][i] = false;
		g_bThreadRun[THD_SEARCH][i] = false;  
	}

}
void CCapClientDlg::ReleaseWatchFile()
{
	int i;
 	for( i = 0; i < MAX_REC_PATH; i++)
	{
 		StopWatchThread(i);
		StopSearchThread(i);
	}	
	DeleteCriticalSection (&g_crtSendFile);
}
void CCapClientDlg::StartWatchThread(int nCur)
{
	DWORD atrb = GetFileAttributes(g_RecPath[nCur].szPath);
	if (atrb != 0xffffffff && (atrb & FILE_ATTRIBUTE_DIRECTORY))
	{
		char szLog[MAX_PATH];
		sprintf_s(szLog,"%sDkqLog.txt",g_RecPath[nCur].szPath);
		if (access(szLog,0) != 0 )
		{
			FILE *fp = fopen(szLog,"wt");
			if(fp != NULL)
			{
				fputs("DkqLog.txt\n",fp);
				fflush(fp);
				fclose(fp);fp=NULL;
			}
		}
		g_hThreads[THD_WATCH][nCur] =  CreateThread(NULL,0,ThreadWatchFile,this,CREATE_SUSPENDED,&g_nThreadIDs[THD_WATCH][nCur]);
		if( g_hThreads[THD_WATCH][nCur]!=NULL )
		{
			g_bThreadRun[THD_WATCH][nCur] = true ;
			ResumeThread(g_hThreads[THD_WATCH][nCur]);
		}
	}
}
void CCapClientDlg::StopWatchThread(int nCur)
{
	if(g_bThreadRun[THD_WATCH][nCur] == false)
	{
		return ;
	}
	if( NULL != g_hThreads[THD_WATCH][nCur] )
	{
		g_bThreadRun[THD_WATCH][nCur] = false;
		char szTmpFile[MAX_PATH];
		sprintf_s(szTmpFile,"%sDkqTmp.txt",g_RecPath[nCur].szPath);
		FILE *fp = fopen(szTmpFile,"w");
		if(fp != NULL)
		{
			fclose(fp);fp=NULL;
		}
		int   nCyc = 0 ;
		DWORD dwWait = 0;
		for(int i=0;i<0x0fffffff;i++)
		{
			dwWait = WaitForSingleObject(g_hThreads[THD_WATCH][nCur],100);
			if( WAIT_FAILED   == dwWait || WAIT_OBJECT_0 == dwWait )
			{
				break;
			}
			nCyc++;
			if(nCyc > 10)
			{
				nCyc = 0 ;
				DeleteFile(szTmpFile);
				fp = fopen(szTmpFile,"w");
				if(fp != NULL)
				{
					fclose(fp);fp=NULL;
				}
			}
		}		
		if( NULL != g_hThreads[THD_WATCH][nCur] )
		{
			CloseHandle (g_hThreads[THD_WATCH][nCur]);
			g_hThreads[THD_WATCH][nCur] = NULL;
		}
	}
}
void CCapClientDlg::StartSearchThread(int nCur)
{
	DWORD atrb = GetFileAttributes(g_RecPath[nCur].szPath);
	if (atrb != 0xffffffff && (atrb & FILE_ATTRIBUTE_DIRECTORY))
	{
		char szLog[MAX_PATH];
		sprintf_s(szLog,"%sDkqLog.txt",g_RecPath[nCur].szPath);
		if (access(szLog,0) != 0 )
		{
			FILE *fp = fopen(szLog,"wt");
			if(fp != NULL)
			{
				fputs("DkqLog.txt\n",fp);
				fflush(fp);
				fclose(fp);fp=NULL;
			}
		}
		g_hThreads[THD_SEARCH][nCur] =  CreateThread(NULL,0,ThreadSearchFile,this,CREATE_SUSPENDED,&g_nThreadIDs[THD_SEARCH][nCur]);
		if( g_hThreads[THD_SEARCH][nCur]!=NULL )
		{
			g_bThreadRun[THD_SEARCH][nCur] = true;
			ResumeThread(g_hThreads[THD_SEARCH][nCur]);
		}
	}
}
void CCapClientDlg::StopSearchThread(int nCur)
{
	if(g_bThreadRun[THD_SEARCH][nCur] == false)
	{
		return ;
	}
	if(NULL != g_hThreads[THD_SEARCH][nCur] )
	{
		g_bThreadRun[THD_SEARCH][nCur] = false;
 		DWORD dwWait = 0;
		for(int i=0;i<0x0fffffff;i++)
		{
			dwWait = WaitForSingleObject(g_hThreads[THD_SEARCH][nCur],100);
			if( WAIT_FAILED   == dwWait || WAIT_OBJECT_0 == dwWait )
			{
				break;
			}
 		}		
		if (g_hThreads[THD_SEARCH][nCur])
		{
			CloseHandle (g_hThreads[THD_SEARCH][nCur]);
			g_hThreads[THD_SEARCH][nCur] = NULL;
		}
	}
}